<template>
  <div>
    <h3>一个表格里面单个字段合并</h3>
    <div>
      如下场景是第一列数据需要列项合并，然后将子项的检测结果向上做汇总处理
    </div>

    <el-table :data="checkDetailList" :span-method="arraySpanMethod">
      <el-table-column label="常规检查" align="center">
        <el-table-column
          width="100"
          label="检测分类"
          prop="firstLevelName"
        ></el-table-column>
        <el-table-column
          width="140"
          label="检测项目"
          prop="secondLevelName"
        ></el-table-column>
        <el-table-column label="检测内容" prop="checkContent"></el-table-column>
        <el-table-column label="检测结果" width="100" prop="detailResult"></el-table-column>
        <el-table-column label="异常情况与建议">
          <template slot-scope="{ row }">
            <div
              v-for="(item, index) in mergeSuggestion(row.thirdLevelRespList)"
              :key="index"
            >
              {{ index + 1 }}.{{ item.checkName }}{{ item.detailResult }}
              <span style="margin: 0 8px; font-weight: 500">建议:</span
              >{{ item.suggestion }}
            </div>
          </template>
        </el-table-column>
      </el-table-column>
    </el-table>
  </div>
</template>

<script>
import { countBy } from 'lodash-es'
import {singleTableMergeData} from './data'

export const mergeTableCell = (data, dataIndex) => {
  return data
    .reduce((result, item) => {
      if (result.indexOf(item[dataIndex]) < 0) {
        result.push(item[dataIndex])
      }
      return result
    }, [])
    .reduce((result, name) => {
      const children = data.filter((item) => item[dataIndex] === name)
      result = result.concat(
        children.map((item, index) => ({
          ...item,
          [dataIndex + 'RowSpan']: index === 0 ? children.length : 0
        }))
      )
      return result
    }, [])
}

export default {
  name: 'index',
  data () {
    return {
      checkDetailList: []
    }
  },
  mounted () {
    this.getData()
  },
  methods: {
    getData () {
      let list = singleTableMergeData
      list.forEach(item => {
        // 检测内容 - 从thirdLevelRespMap中拿到所有的checkName即是检测内容
        item.checkContent = ''
        item.thirdLevelRespList = item.thirdLevelRespList || []

        item.checkContent = item.thirdLevelRespList.map(item => item.checkName).join(',')

        item.thirdLevelRespList.forEach(detailItem => {
          // 会返回一个 {abnormal: 1, normal: 2, notCheck: 3} 的结构， 可能是1个key 可能是2个key,可能是3个key
          detailItem.checkStatus = countBy(detailItem.detailCheckOrderDetailResultRespList, 'checkStatus')
        })

        item.detailResultMap = {
          abnormal: 0,
          normal: 0,
          notCheck: 0
        }
        // 对 item.thirdLevelRespList中检测结果进行汇总
        item.thirdLevelRespList.forEach(thirdLevelItem => {
          thirdLevelItem.detailCheckOrderDetailResultRespList.forEach(i => {
            let key = i.checkStatus
            item.detailResultMap[key] += 1
          })
        })

        if (item.detailResultMap.abnormal) {
          item.detailResult = '异常'
        } else if (item.detailResultMap.normal) {
          item.detailResult = '正常'
        } else {
          item.detailResult = '未检测'
        }
      })

      // 使用mergeTableCell 返回代码合并属性的字段，然后直接用，当使用arraySpanMethod 方法的时候，直接拿配置即可，不需要在这个方法里处理数据
      this.checkDetailList = mergeTableCell(list, 'firstLevelName')
    },
     /**
     * 处理异常情况与建议
     */
    mergeSuggestion(list) {
      list = list.filter(item => {
        let resultRespList = item.detailCheckOrderDetailResultRespList

        resultRespList = resultRespList.filter(p => {
          return !(['normal', 'notCheck'].includes(p.checkStatus) && p.detailResult === null && p.suggestion === null)
        })

        // 说明是有异常项的
        if (resultRespList.length) {
          return item
        }
      })

      // 将list中detailCheckOrderDetailResultRespList 展平
      let totalList = []

      list.forEach(item => {
        let detailCheckOrderDetailResultRespList = item.detailCheckOrderDetailResultRespList || []

        detailCheckOrderDetailResultRespList.forEach(resultItem => {
          delete resultItem.checkStatus
          totalList.push({
            ...item,
            ...resultItem
          })
        })
      })
      return totalList
    },
    /**
     * 返回列项合并的对象
     */
    arraySpanMethod ({ row, column, rowIndex, columnIndex }) {
      // 当为第一列， 则处理合并
      if (columnIndex === 0) {
        return {
          rowspan: row.firstLevelNameRowSpan,
          colspan: 1
        }
      }
    }
  }
}
</script>

<style lang="less" scoped>
</style>
